/**
 * MIT License
 *
 * Copyright (c) 2024 小村程序员
 * Email: 397237738@qq.com
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

package org.open.cobertura.core.analyzer;

import org.open.cobertura.data.CoberturaCoverageCounter;
import org.open.cobertura.data.ICoberturaClassCovered;
import org.open.cobertura.data.ICoberturaPackageCovered;
import org.open.cobertura.util.DataUtil;

import java.util.ArrayList;
import java.util.List;


/**
 * 覆盖率构建类
 */
public class CoberturaCoveredFactory {

    private List<ICoberturaPackageCovered> coberturaPackageCovered;

    public CoberturaCoveredFactory() {
        coberturaPackageCovered=new ArrayList<>();
    }

    /**
     * 添加包的覆盖率
     * @param coberturaPackageCovered
     */
    public void addPackageCovered(CoberturaPackageCoveredImpl coberturaPackageCovered){
        boolean isExists=false;
        for(int i=0;i<this.coberturaPackageCovered.size();i++){
            ICoberturaPackageCovered coberturaClassCovered=this.coberturaPackageCovered.get(i);
            if(coberturaClassCovered.getPackageName().equals(coberturaPackageCovered.getPackageName())){
                CoberturaCoverageCounter classCounter=coberturaClassCovered.getClassCounter();
                classCounter.coveredCount+=coberturaPackageCovered.getClassCounter().coveredCount;
                classCounter.missedCount+=coberturaPackageCovered.getClassCounter().missedCount;
                classCounter.totalCount+=coberturaPackageCovered.getClassCounter().totalCount;
                classCounter.coveredRate= DataUtil.calculateCoverageRatio(classCounter.coveredCount,classCounter.totalCount);

                CoberturaCoverageCounter methodCounter=coberturaClassCovered.getMethodCounter();
                methodCounter.coveredCount+=coberturaPackageCovered.getMethodCounter().coveredCount;
                methodCounter.missedCount+=coberturaPackageCovered.getMethodCounter().missedCount;
                methodCounter.totalCount+=coberturaPackageCovered.getMethodCounter().totalCount;
                methodCounter.coveredRate= DataUtil.calculateCoverageRatio(methodCounter.coveredCount,methodCounter.totalCount);

                CoberturaCoverageCounter complexityCounter=coberturaClassCovered.getComplexityCounter();
                complexityCounter.coveredCount+=coberturaPackageCovered.getComplexityCounter().coveredCount;
                complexityCounter.missedCount+=coberturaPackageCovered.getComplexityCounter().missedCount;
                complexityCounter.totalCount+=coberturaPackageCovered.getComplexityCounter().totalCount;
                complexityCounter.coveredRate= DataUtil.calculateCoverageRatio(complexityCounter.coveredCount,complexityCounter.totalCount);

                CoberturaCoverageCounter instructionCounter=coberturaClassCovered.getInstructionCounter();
                instructionCounter.coveredCount+=coberturaPackageCovered.getInstructionCounter().coveredCount;
                instructionCounter.missedCount+=coberturaPackageCovered.getInstructionCounter().missedCount;
                instructionCounter.totalCount+=coberturaPackageCovered.getInstructionCounter().totalCount;
                instructionCounter.coveredRate= DataUtil.calculateCoverageRatio(instructionCounter.coveredCount,instructionCounter.totalCount);

                CoberturaCoverageCounter branchCounter=coberturaClassCovered.getBranchCounter();
                branchCounter.coveredCount+=coberturaPackageCovered.getBranchCounter().coveredCount;
                branchCounter.missedCount+=coberturaPackageCovered.getBranchCounter().missedCount;
                branchCounter.totalCount+=coberturaPackageCovered.getBranchCounter().totalCount;
                branchCounter.coveredRate= DataUtil.calculateCoverageRatio(branchCounter.coveredCount,branchCounter.totalCount);

                CoberturaCoverageCounter lineCounter=coberturaClassCovered.getLineCounter();
                lineCounter.coveredCount+=coberturaPackageCovered.getLineCounter().coveredCount;
                lineCounter.missedCount+=coberturaPackageCovered.getLineCounter().missedCount;
                lineCounter.totalCount+=coberturaPackageCovered.getLineCounter().totalCount;
                lineCounter.coveredRate= DataUtil.calculateCoverageRatio(lineCounter.coveredCount,lineCounter.totalCount);
                coberturaClassCovered.getCoberturaClassCovered().addAll(coberturaPackageCovered.getCoberturaClassCovered());
                this.coberturaPackageCovered.set(i,coberturaClassCovered);
                isExists=true;
            }
        }
        if(isExists==false) {
            this.coberturaPackageCovered.add(coberturaPackageCovered);
        }
    }

    /**
     * 得到覆盖率数据，数据的层级关系从包开始，依次为包->类->方法->行
     * CoberturaPackageCovered 包覆盖率
     *      |_____________CoberturaClassCovered 类覆盖率
     *             |______________CoberturaMethodCovered 方法覆盖率
     * @return
     */
    public List<ICoberturaPackageCovered> getCoberturaCovered(){
        return coberturaPackageCovered;
    }

}
